%{ open Ast %}


%token SEMI LPAREN RPAREN LBRACE RBRACE COMMA POINT
%token MULTIPLE SINGLE DROP TEXT TITLE LINK JUMP
%token ASSIGN
%token IMAGE
%token JUMPBUTTON
%token NEW
%token QUESTION
%token QUESTIONSET 
%token DISPLAY
%token ADDQUESTION

%token <string> STRING_LITERAL
%token <string> LITERAL
%token <string> ID
%token EOF


%left ASSIGN

%start program
%type <Ast.program>  program

%%

program: 
											{ ([],[]) } 
				| program decl              { ($2 :: (fst $1)), snd $1 }  
				| program func_def 			{ fst $1, ($2 :: snd $1) }


func_def : 
        ID LPAREN args_opt RPAREN LBRACE decl_list stmt_list RBRACE { { fname = $1;
	 																     formals = $3;
	 																     locals = List.rev $6;
	 																     body = List.rev $7 }} 
args_opt:
        /*nothing*/             {[]}
        |args_list              {List.rev $1}
         
         						
args_list :
				def_args		             {[$1]}
                |args_list COMMA  def_args { $3::$1 }
				      									
def_args:  
            datatype ID                         {($1,$2)}

decl_list: 
											{[]}
		    |decl_list decl               { $2::$1 }			
decl: 
		   datatype var_opt SEMI				       {($1,$2) }
		   |datatype ID ASSIGN NEW QUESTIONSET LPAREN RPAREN SEMI {($1,[$2])}		


datatype:
    QUESTION							 { Question }
    |IMAGE								 { Image }
    |JUMPBUTTON						     { Jump }
    |QUESTIONSET                         { QuestionSet }


stmt_list: 
														{ [ ] }
				|stmt_list stmt							{ $2::$1 }

stmt:
		 expr SEMI							{ Expr($1) }
		|LBRACE stmt_list RBRACE					{ Block(List.rev $2) }
		

expr:
     /*assign value to question*/
       |ID POINT MULTIPLE ASSIGN LBRACE string_opt RBRACE 		   { Atype($1,Multiple,$6) }
	   |ID POINT SINGLE ASSIGN LBRACE string_opt RBRACE				{ Atype($1,Single,$6) }
	   |ID POINT DROP ASSIGN LBRACE string_opt RBRACE		        { Atype($1,Drop,$6) }
	   |ID POINT TEXT ASSIGN LBRACE LITERAL RBRACE				   { Text($1,$6) }
	   |ID POINT TITLE ASSIGN STRING_LITERAL						 { Title($1,$5) }
       |ID POINT ADDQUESTION LPAREN var_opt RPAREN					  { Addquestion($1,$5) }
       |ID POINT LINK ASSIGN STRING_LITERAL                             {Link($1, $5)}
       |ID POINT JUMP ASSIGN STRING_LITERAL                             {Jup($1, $5)}
       |DISPLAY  var_opt												{ Display($2) }    
       |ID LPAREN var_opt RPAREN 									{ Call($1, $3) }

       string_opt:
                                                        {[ ]}								      	 
					|stringlist						{ List.rev $1 }
       stringlist:
				STRING_LITERAL						{ [$1] } 
	    		| stringlist COMMA STRING_LITERAL  { $3::$1 }

var_opt:
                                                                {[ ]}
    	 |var_decl												{List.rev $1}

var_decl : 
			 ID											{ [$1] }
			|var_decl COMMA ID 							{ $3::$1 }
   

	
	






